﻿namespace PrismEx.Events
{
    using System;
    using System.Reactive.Linq;
    using System.Reactive.Subjects;

    using Microsoft.Practices.Prism.Events;

    public class ReactiveEvent<T> : CompositePresentationEvent<T>
    {
        private readonly Subject<T> eventSource;

        public ReactiveEvent()
        {
            eventSource = new Subject<T>();
        }

        public override void Publish(T payload)
        {
            eventSource.OnNext(payload);
        }

        public override SubscriptionToken Subscribe(Action<T> action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate<T> filter)
        {
            var subscription = eventSource.Where(t => filter == null || filter(t)).Subscribe(action);
            return new ReactiveSubscriptionToken(subscription);
        }

        public override void Unsubscribe(SubscriptionToken token)
        {
            var reactiveToken = token as ReactiveSubscriptionToken;

            if (reactiveToken != null)
            {
                reactiveToken.Dispose();
            }
        }

        public override void Unsubscribe(Action<T> subscriber)
        {
            throw new NotImplementedException("Use overload with SubscriptionToken to unsubsribe.");
        }
    }
}